import 'dart:async';

import 'package:event_bus/event_bus.dart';
import 'package:todo_app/thirdpart/flutter_fms/flutter_fms.dart';
import 'package:todo_app/utils/call/CallHelper.dart';
import 'package:todo_app/utils/call/contexts/IdleContext.dart';
import 'contexts/ConnectingUIContext.dart';
import 'contexts/TalkUIContext.dart';
import 'states/ConnectingState.dart';
import 'states/IdleState.dart';
import 'states/TalkState.dart';
import 'transitions/CallConnectTransition.dart';
import 'transitions/CallOutTransition.dart';
import 'transitions/EndTransition.dart';
import 'transitions/TalkTransition.dart';

class CallFms extends IStateMachine {
  StreamSubscription<CallTransitionEvent>? subscription;
  EventBus eventBus = EventBus();

  init() {
    addState(
      IdleState()
      ..addTransition(CallOutTransition())
      ..addTransition(CallConnectTransition())
    );
    addState(
      ConnectingState()
      ..addTransition(EndTransition())
      ..addTransition(TalkTransition())
    );
    addState(
      TalkState()
      ..addTransition(EndTransition())
    );

    setCurState(IdleState());

    /// 添加监听
    subscription = eventBus.on<CallTransitionEvent>().listen((CallTransitionEvent event) async {
      switch (event.type) {
        case CallTransitionType.DISCONNECTED:
          IdleContext context = event.payload as IdleContext;
          updateState(EndTransition(idleState: IdleState(context: context)));
          break;
        case CallTransitionType.CALL_OUT:
        case CallTransitionType.CALL_IN:
        case CallTransitionType.CONNECTING:
          ConnectingUIContext context = event.payload as ConnectingUIContext;
          ConnectingState connectingState = ConnectingState(context: context);
          if(context.requestSuccess == true) {
            updateState(CallConnectTransition(connectingState: connectingState));
          } else {
            updateState(CallOutTransition(connectingState: connectingState));
          }
          CallHelper.setAppState();
          break;
        case CallTransitionType.CONNECTED:
          TalkUIContext context = event.payload as TalkUIContext;
          updateState(TalkTransition(
            talkState: TalkState(
              context: context
            )
          ));
          CallHelper.setAppState();
          break;
        default:
          break;
      }
    });
  }

  dispose() {
    /// 移除监听
    subscription?.cancel();
  }
}


enum CallTransitionType {
  CALL_IN, // 呼入
  CALL_OUT, // 呼出
  CONNECTING, // 建立链接
  CONNECTED, // 通话建立
  DISCONNECTED // 通话已结束
}

class CallTransitionEvent {
  final CallTransitionType type;
  final dynamic payload;

  CallTransitionEvent({required this.type, this.payload});
}
